Crate leptos_router

source ·
Expand description

§Leptos Router

Leptos Router is a router and state management tool for web applications written in Rust using the Leptos web framework. It is ”isomorphic”, i.e., it can be used for client-side applications/single-page apps (SPAs), server-side rendering/multi-page apps (MPAs), or to synchronize state between the two.

§Philosophy

Leptos Router is built on a few simple principles:

  1. URL drives state. For web applications, the URL should be the ultimate source of truth for most of your app’s state. (It’s called a Universal Resource Locator for a reason!)

  2. Nested routing. A URL can match multiple routes that exist in a nested tree and are rendered by different components. This means you can navigate between siblings in this tree without re-rendering or triggering any change in the parent routes.

  3. Progressive enhancement. The A and Form components resolve any relative nested routes, render actual <a> and <form> elements, and (when possible) upgrading them to handle those navigations with client-side routing. If you’re using them with server-side rendering (with or without hydration), they just work, whether JS/WASM have loaded or not.

§Example

use leptos::*;
use leptos_router::*;

#[component]
pub fn RouterExample() -> impl IntoView {
  view! {

    <div id="root">
      // we wrap the whole app in a <Router/> to allow client-side navigation
      // from our nav links below
      <Router>
        // <nav> and <main> will show on every route
        <nav>
          // LR will enhance the active <a> link with the [aria-current] attribute
          // we can use this for styling them with CSS like `[aria-current] { font-weight: bold; }`
          <A href="contacts">"Contacts"</A>
          // But we can also use a normal class attribute like it is a normal component
          <A href="settings" class="my-class">"Settings"</A>
          // It also supports signals!
          <A href="about" class=move || "my-class">"About"</A>
        </nav>
        <main>
          // <Routes/> both defines our routes and shows them on the page
          <Routes>
            // our root route: the contact list is always shown
            <Route
              path=""
              view=ContactList
            >
              // users like /gbj or /bob
              <Route
                path=":id"
                view=Contact
              />
              // a fallback if the /:id segment is missing from the URL
              <Route
                path=""
                view=move || view! { <p class="contact">"Select a contact."</p> }
              />
            </Route>
            // LR will automatically use this for /about, not the /:id match above
            <Route
              path="about"
              view=About
            />
          </Routes>
        </main>
      </Router>
    </div>
  }
}

type ContactSummary = (); // TODO!
type Contact = (); // TODO!()

// contact_data reruns whenever the :id param changes
async fn contact_data(id: String) -> Contact {
  todo!()
}

// contact_list_data *doesn't* rerun when the :id changes,
// because that param is nested lower than the <ContactList/> route
async fn contact_list_data() -> Vec<ContactSummary> {
  todo!()
}

#[component]
fn ContactList() -> impl IntoView {
  // loads the contact list data once; doesn't reload when nested routes change
  let contacts = create_resource(|| (), |_| contact_list_data());
  view! {

    <div>
      // show the contacts
      <ul>
        {move || contacts.read().map(|contacts| view! { <li>"todo contact info"</li> } )}
      </ul>

      // insert the nested child route here
      <Outlet/>
    </div>
  }
}

#[component]
fn Contact() -> impl IntoView {
  let params = use_params_map();
  let data = create_resource(

    move || params.with(|p| p.get("id").cloned().unwrap_or_default()),
    move |id| contact_data(id)
  );
  todo!()
}

#[component]
fn About() -> impl IntoView {
  todo!()
}

§Module Route Definitions

Routes can also be modularized and nested by defining them in separate components, which can be located in and imported from other modules. Components that return <Route/> should be marked #[component(transparent)], as in this example:

use leptos::*;
use leptos_router::*;

#[component]
pub fn App() -> impl IntoView {
  view! {
    <Router>
      <Routes>
        <Route path="/" view=move || {
          view! { "-> /" }
        }/>
        <ExternallyDefinedRoute/>
      </Routes>
    </Router>
  }
}

// `transparent` here marks the component as returning data (a RouteDefinition), not a view
#[component(transparent)]
pub fn ExternallyDefinedRoute() -> impl IntoView {
  view! {
    <Route path="/some-area" view=move || {
      view! { <div>
        <h2>"Some Area"</h2>
        <Outlet/>
      </div> }
    }>
      <Route path="/path-a/:id" view=move || {
        view! { <p>"Path A"</p> }
      }/>
      <Route path="/path-b/:id" view=move || {
        view! { <p>"Path B"</p> }
      }/>
    </Route>
  }
}

§Feature Flags

  • csr Client-side rendering: Generate DOM nodes in the browser
  • ssr Server-side rendering: Generate an HTML string (typically on the server)
  • hydrate Hydration: use this to add interactivity to an SSRed Leptos app
  • nightly: On nightly Rust, enables the function-call syntax for signal getters and setters.

Important Note: You must enable one of csr, hydrate, or ssr to tell Leptos which mode your app is operating in.

Re-exports§

  • pub use matching::*;

Macros§

Structs§

Enums§

  • Represents an HTTP method that can be handled by this route.
  • An error that occurs during navigation.
  • Errors that can occur while parsing params using Params.
  • Indicates which rendering mode should be used for this route during server-side rendering.
  • The mode to use when rendering the route statically. On mode Upfront, the route will be built with the server is started using the provided static data. On mode Incremental, the route will be built on the first request to it and then cached and returned statically for subsequent requests.
  • Declares how you would like to handle trailing slashes in Route paths. This can be set on Router and overridden in crate::components::Route

Traits§

  • Tries to deserialize a type from form data. This can be used for client-side validation during form submission.
  • The Router relies on a RouterIntegrationContext, which tells the router how to find things like the current URL, and how to navigate to a new page. The History trait can be implemented on any type to provide this information.
  • A simple method of deserializing key-value data (like route params or URL search) into a concrete data type. Self should typically be a struct in which each field’s type implements FromStr.
  • Describes a value that is either a static or a reactive URL, i.e., a String, a &str, or a reactive Fn() -> String.

Functions§

  • An HTML a progressively enhanced to use client-side routing.
  • Automatically turns a server Action into an HTML form progressively enhanced to use client-side routing.
  • Displays the child route nested in a parent route, allowing you to control exactly where that child route is displayed. Renders nothing if there is no nested child.
  • Contains route definitions and manages the actual routing process, with animated transitions between routes.
  • An HTML form progressively enhanced to use client-side routing.
  • Automatically turns a server MultiAction into an HTML form progressively enhanced to use client-side routing.
  • Displays the child route nested in a parent route, allowing you to control exactly where that child route is displayed. Renders nothing if there is no nested child.
  • Describes a route that is guarded by a certain condition. This works the same way as <Route/>, except that if the condition function evaluates to false, it redirects to redirect_path instead of displaying its view.
  • Redirects the user to a new URL, whether on the client side or on the server side. If rendered on the server, this sets a 302 status code and sets a Location header. If rendered in the browser, it uses client-side navigation to redirect. In either case, it resolves the route relative to the current route. (To use an absolute path, prefix it with /).
  • Describes a portion of the nested layout of the app, specifying the route it should match, the element it should display, and data that should be loaded alongside the route.
  • Provides for client-side and server-side routing. This should usually be somewhere near the root of the application.
  • Contains route definitions and manages the actual routing process.
  • A visible indicator that the router is in the process of navigating to another route.
  • Describes a portion of the nested layout of the app, specifying the route it should match, the element it should display, and data that should be loaded alongside the route.
  • Creates a reactive location from the given path and state.
  • Constructs a signal synchronized with a specific URL query parameter.
  • Generates a list of all routes this application could possibly serve. This returns the raw routes in the leptos_router format. Odds are you want generate_route_list() from either the actix or axum integrations if you want to work with their router.
  • Generates a list of all routes this application could possibly serve. This returns the raw routes in the leptos_router format. Odds are you want generate_route_list() from either the actix or axum integrations if you want to work with their router.
  • Provides a function that can be used to redirect the user to another absolute path, on the server. This should set a 302 status code and an appropriate Location header.
  • Returns the current Location, which contains reactive variables
  • Returns a function that can be used to navigate to a new route.
  • Returns the current route params, parsed into the given type, or an error.
  • Returns a raw key-value map of route params.
  • Returns the current URL search query, parsed into the given type, or an error.
  • Returns a raw key-value map of the URL search query.
  • Resolves the given path relative to the current route.
  • Returns the current RouteContext, containing information about the matched route.
  • Returns the data for the current route, which is provided by the data prop on <Route/>.
  • Returns the current RouterContext, containing information about the router’s state.

Type Aliases§